using System.Collections.Generic;
using System.Threading.Tasks;
using Abp.Authorization;
using Abp.Domain.Repositories;
using HCD.Hcd.Dtos;
using HCD.Entities;
using HCD.Hcd;
using HCD.Mdt;
using System.Linq;
using Abp.Application.Services;
using Microsoft.EntityFrameworkCore;
using Z.EntityFramework;
using Z.EntityFramework.Plus;
using Abp.Timing;

namespace HCD.Hcd
{
    /// <summary>
    /// 应用层服务的接口实现方法
    ///</summary>
    [RemoteService(false)]
    public class HcdAppService : EnterpriseAppServiceBase, IHcdAppService
    {
        public IRepository<LabelTypeDict, long> LabelTypeDictRepository { get; set; }
        public IRepository<HcdPatLabels, long> HcdPatLabelsRepository { get; set; }
        public IRepository<HcdMessage, long> HcdMessageRepository { get; set; }
        public IRepository<HcdMaster, long> HcdMasterRepository { get; set; }
        public IRepository<ManagePartingDict, long> ManagePartingDictRepository { get; set; }
        public IRepository<PatientPartingInfo, long> PatientPartingInfoRepository { get; set; }

        /// <summary>
        /// 获取标签类型字典
        /// </summary>
        /// <returns></returns>
        public async Task<List<LabelTypeDto>> GetLabelTypeDicts()
        {
            var list = await LabelTypeDictRepository.GetAllListAsync();
            return ObjectMapper.Map<List<LabelTypeDto>>(list);
        }

        /// <summary>
        /// 获取患者来源科室列表(For左侧筛选列表)
        /// </summary>
        /// <returns></returns>
        public async Task<List<SourceDeptDto>> GetSourceDeptList()
        {
            return await HcdMasterRepository.GetAll().Where(w => w.RemoveManagement != "1").GroupBy(g => new { g.DeptCode, g.DeptName }).Select(s =>
                 new SourceDeptDto
                 {
                     DeptCode = s.Key.DeptCode,
                     DeptName = s.Key.DeptName,
                     Count = s.Count()
                 }
            ).ToListAsync();
        }

        /// <summary>
        /// 获取标签列表(For左侧筛选列表)
        /// </summary>
        /// <returns></returns>
        public async Task<List<LabelTypeDto>> GetLabelTypeList()
        {
            var query = from ld in LabelTypeDictRepository.GetAll()
                        join pl in HcdPatLabelsRepository.GetAll() on ld.LabelTypeCode equals pl.LabelTypeCode into pl_join
                        from x in pl_join.DefaultIfEmpty()
                        orderby ld.LabelTypeCode
                        select new
                        {
                            ld.LabelTypeCode,
                            ld.LabelTypeName,
                            PatLabel = x.LabelTypeCode
                        };
            return await query.GroupBy(g => new { g.LabelTypeCode, g.LabelTypeName }).Select(s => new LabelTypeDto
            {
                LabelTypeCode = s.Key.LabelTypeCode,
                LabelTypeName = s.Key.LabelTypeName,
                Count = s.Where(w => !string.IsNullOrEmpty(w.PatLabel)).Count()
            }).ToListAsync();
        }

        /// <summary>
        /// 获取管理分型列表(For左侧筛选列表)
        /// </summary>
        /// <returns></returns>
        public async Task<List<ManagePartingDto>> GetManagePartingList()
        {
            var query = from mpd in ManagePartingDictRepository.GetAll()
                        join ppi in PatientPartingInfoRepository.GetAll() on mpd.PartingCode equals ppi.PartingCode into ppi_join
                        from x in ppi_join.DefaultIfEmpty()
                        orderby mpd.PartingCode
                        select new
                        {
                            mpd.PartingCode,
                            mpd.PartingName,
                            InfoCode = x.PartingCode
                        };
            return await query.GroupBy(g => new { g.PartingCode, g.PartingName }).Select(s => new ManagePartingDto
            {
                PartingCode = s.Key.PartingCode,
                PartingName = s.Key.PartingName,
                Count = s.Where(w => !string.IsNullOrEmpty(w.InfoCode)).Count()
            }).ToListAsync();
        }

        /// <summary>
        /// 获取在管病人列表（主界面）
        /// </summary>
        /// <param name="Type">查询类型</param>
        /// <param name="TypeValue">查询值</param>
        /// <returns></returns>
        public async Task<List<HcdMasterDto>> GetHcdPatientList(string Type, string TypeValue)
        {
            //按来源科室查询
            if (Type == "1")
            {
                return await GetHcdPatientListByDeptCode(Type, TypeValue);
            }
            //按标签查询
            else if (Type == "2")
            {
                return await GetHcdPatientListByDeptCode(Type, TypeValue);
            }
            //按管理分型查询
            else if (Type == "3")
            {
                return await GetHcdPatientListByDeptCode(Type, TypeValue);
            }
            //按自定义筛选
            else if(Type == "4")
            {
                return await GetHcdPatientListByDeptCode(Type, TypeValue);
            }else{
                return await GetHcdPatientListByDeptCode(Type, TypeValue);
            }
        }
        private async Task<List<HcdMasterDto>> GetHcdPatientListByDeptCode(string Type, string TypeValue)
        {
            //取病人消息
            var queryMess = from hm in HcdMasterRepository.GetAll()
                            join hmess in HcdMessageRepository.GetAll() on new { hm.PatientId, hm.VisitId } equals new { hmess.PatientId, hmess.VisitId }
                            orderby hm.PatientId
                            select new
                            {
                                hm,
                                hmess
                            };
            //按来源科室查
            if(Type=="1") queryMess = queryMess.Where(w => w.hm.DeptCode == TypeValue);
            //按管理分型查
            if (Type=="3") queryMess = queryMess.Where(w => w.hm.PartingCode == TypeValue);
            //取病人标签
            var queryLabel = from hm in HcdMasterRepository.GetAll()
                             join hLabel in HcdPatLabelsRepository.GetAll() on new { hm.PatientId, hm.VisitId } equals new { hLabel.PatientId, hLabel.VisitId }
                             orderby hm.PatientId
                             select new
                             {
                                 hm,
                                 hLabel
                             };
            //按来源科室查
            if (Type == "1") queryLabel = queryLabel.Where(w => w.hm.DeptCode == TypeValue);
            //按病人标签查
            if (Type == "2") queryLabel = queryLabel.Where(w => w.hLabel.LabelTypeCode == TypeValue);
            //按管理分型查
            if (Type == "3") queryLabel = queryLabel.Where(w => w.hm.PartingCode == TypeValue);

            var retMess = (await queryMess.ToListAsync()).GroupBy(g => g.hm, m => m.hmess).Select(s =>
            {
                HcdMasterDto masterDto = new HcdMasterDto();
                masterDto = ObjectMapper.Map<HcdMasterDto>(s.Key);
                masterDto.lstHcdMessage = ObjectMapper.Map<List<HcdMessageDto>>(s.ToList());
                return masterDto;
            }).ToList();
            var retLabel = (await queryLabel.ToListAsync()).GroupBy(g => g.hm, m => m.hLabel).Select(s =>
            {
                HcdMasterDto masterDto = new HcdMasterDto();
                masterDto = ObjectMapper.Map<HcdMasterDto>(s.Key);
                masterDto.lstHcdPatLabels = ObjectMapper.Map<List<HcdPatLabelsDto>>(s.ToList());
                return masterDto;
            }).ToList();
            //标签信息列表合并到主对象
            retMess.AsParallel().ForAll(obj =>
            {
                obj.lstHcdPatLabels = retLabel.FirstOrDefault(w => w.PatientId == obj.PatientId)?.lstHcdPatLabels;
            });
            return retMess;
        }

        /// <summary>
        /// 获取病人标签
        /// </summary>
        /// <param name="PatientId">病人Id</param>
        /// <param name="VisitId">病人住院标识</param>
        /// <returns></returns>
        public async Task<List<HcdPatLabelsDto>> GetHcdPatLabelsList(string PatientId, string VisitId)
        {
            var list = HcdPatLabelsRepository.GetAll();
            return await ObjectMapper.ProjectTo<HcdPatLabelsDto>(list.Where(w => w.PatientId == PatientId && w.VisitId == VisitId)).ToListAsync();
        }

        /// <summary>
        /// 更新消息状态为已读
        /// </summary>
        /// <param name="lstMessage">未读消息列表</param>
        /// <returns></returns>
        public async Task<bool> UpdateMessageStatus(List<HcdMessageEditDto> lstMessage)
        {
            if(lstMessage !=null && lstMessage.Count > 0)
            {
                var ids = lstMessage.Select(m=>m.Id);
                await HcdMessageRepository.GetAll().Where(m=>ids.Contains(m.Id)).UpdateAsync(m=>new HcdMessage
                {
                    MessageStatus = "1" 
                });
            }
            return true;
        }

        /// <summary>
        /// 设置病人为随访病人
        /// </summary>
        /// <param name="item">病人主记录的物理主键</param>
        /// <returns></returns>
        public  async Task<int> UpdatePatientIntoFollowUp(HcdMasterFollowUpDto item)
        {
            return await HcdMasterRepository.GetAll().Where(w => w.Id == item.Id).UpdateAsync(u => new HcdMaster
            {
                FollowUpStatus = item.FollowUpStatus,
                FollowUpOperator = item.FollowUpOperator,
                FollowUpGroup = item.FollowUpGroup,
                FollowUpDateTime = Clock.Now
            });
        }

        /// <summary>
        /// 将病人移除院内管理
        /// </summary>
        /// <param name="item">病人主记录的物理主键</param>
        /// <returns></returns>
        public async Task<int> SetPatientOutofManagement(HcdMasterRemoveDto item)
        {
            return await HcdMasterRepository.GetAll().Where(w => w.Id == item.Id).UpdateAsync(u => new HcdMaster
            {
                RemoveManagement = item.RemoveManagement,
                RemoveOperator = item.RemoveOperator,
                RemoveDateTime = Clock.Now
            });
        }
    }
}


